package org.example.leetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <a href="https://leetcode.cn/problems/3sum/">三数之和</a>
 *
 *
 * @author shenguangyang
 */
public class N015_ThreeSum {
    /**
     * 解法: 排序 + 双指针
     */
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.parallelSort(nums);
        List<List<Integer>> out = new ArrayList<>();
        int length = nums.length;
        for (int i = 0; i < length; i++) {
            if (nums[i] > 0) {
                return out;
            }
            // 去除重复解
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int left = i + 1;
            int right = length - 1;
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum > 0) {
                    right = right - 1;
                } else if (sum < 0) {
                    left = left + 1;
                } else {
                    // 添加集合
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    out.add(list);

                    // 对左指针区域进行去除重复解
                    while (left < right && nums[left] == nums[left + 1]) {
                        left = left + 1;
                    }

                    // 对右指针区域进行去除重复解
                    while (left < right && nums[right] == nums[right - 1]) {
                        right = right - 1;
                    }
                    right = right - 1;
                    left = left + 1;
                }
            }
        }
        return out;
    }

    public static void main(String[] args) {
        N015_ThreeSum threeSum = new N015_ThreeSum();
        int[] nums = new int[] {-1,0,1,2,-1,-4};
        List<List<Integer>> lists = threeSum.threeSum(nums);
        System.out.println(lists);
    }
}
